package com.app.business.service;

import com.app.business.calculate.CalculateUtils;
import com.app.business.en.Status;
import com.app.business.model.*;
import com.app.business.utils.UserPermissionUtil;
import com.app.system.jpa.JpaBaseDao;
import com.app.system.jpa.PageBean;
import com.app.system.jpa.Wrapper;
import com.app.system.permission.model.UserInfo;
import com.app.system.utils.CollectionUtils;
import com.app.system.utils.ParamUtils;
import com.app.system.utils.WebUtils;
import com.app.system.utils.dataType.BigDecimalUtils;
import com.app.system.utils.dataType.DateUtils;
import com.app.system.utils.dataType.StringUtils;
import com.app.system.utils.exception.Precondition;
import com.app.system.utils.exception.Response;
import com.google.common.collect.Maps;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.*;

/**
 * 基础信息业务层
 * Created by drl on 2019/2/11.
 */
@Service
@SuppressWarnings("all")
public class ContractService extends JpaBaseDao<Contract, Integer> {

    @Autowired
    private HouseService houseService;
    @Autowired
    private CarLotService carLotService;
    @Autowired
    private StorageRoomService storageRoomService;
    @Autowired
    private ActionHistoryService actionHistoryService;
    @Autowired
    private ShopHouseService shopHouseService;

    /**
     * 分页处理
     *
     * @return
     */
    public PageBean<Contract> getContractPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("c.preChooseDate,c.chooseHouseNum,c.id");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();

        UserPermissionUtil.zsProjectUserLimit(wrapper);        //用户只能看到已经分配给自己的项目下的协议信息

        return this.pageHql(wrapper);
    }

    public PageBean<Contract> getFinanceSettleStatusPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.bzYyDate desc");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.andEq("c.financeSettleStatus", 2);

        wrapper.initSearchParams();

        UserPermissionUtil.zsProjectUserLimit(wrapper);        //用户只能看到已经分配给自己的项目下的协议信息

        return this.pageHql(wrapper);
    }

    /**
     * 财务未复核列表
     *
     * @return
     */
    public PageBean<Contract> getAdjustAreaContractPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp ");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        PageBean pageBean = new PageBean();
        pageBean.setPageSize(Integer.MAX_VALUE);
        Wrapper wrapper = new Wrapper(pageBean, query, null, orderBy);

        wrapper.initSearchParams();
        UserPermissionUtil.zsProjectUserLimit(wrapper);        //用户只能看到已经分配给自己的项目下的协议信息

        return this.pageHql(wrapper);
    }


    /**
     * 财务导出处理
     *
     * @return
     */
    public PageBean<Contract> getExcelContractPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp ");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        PageBean pageBean = new PageBean();
        pageBean.setPageSize(Integer.MAX_VALUE);
        Wrapper wrapper = new Wrapper(pageBean, query, null, orderBy);
        wrapper.andEq("c.financeCheckStatus", Status.YES.getIndex());

        wrapper.initSearchParams();
        UserPermissionUtil.zsProjectUserLimit(wrapper);        //用户只能看到已经分配给自己的项目下的协议信息

        return this.pageHql(wrapper);
    }

    /**
     * 选房顺序号验证查重
     *
     * @param contractId
     * @param zsProjectId
     * @param chooseHouseNum
     * @return
     */
    public String validateChooseHouseNum(Integer contractId, Integer zsProjectId, String chooseHouseNum) {
        StringBuffer hql = new StringBuffer(" select * from contract where id != :contractId and zs_project_id =:zsProjectId and choose_house_num =:chooseHouseNum ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("chooseHouseNum", chooseHouseNum);
        map.put("zsProjectId", zsProjectId);
        map.put("contractId", contractId);

        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            return "选房号已存在";
        }
        return null;

    }


    /**
     * 协议编号验证查重
     *
     * @param contractId
     * @param zsProjectId
     * @param chooseHouseNum
     * @return
     */
    public String validateContractCode(Integer contractId, Integer zsProjectId, String contractCode) {
        StringBuffer hql = new StringBuffer(" select * from contract where id != :contractId and zs_project_id =:zsProjectId and contract_code =:contractCode ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("contractCode", contractCode);
        map.put("zsProjectId", zsProjectId);
        map.put("contractId", contractId);

        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            return "协议编号已存在";
        }
        return null;

    }

    /**
     * 分页处理根据征收项目id查询（安排选房时间，打印选房通知单使用）
     *
     * @return
     */
    public PageBean<Contract> contractPageBeanByZsProjectId(Integer zsProjectId) {
        //查询语句
        StringBuffer query = new StringBuffer(" c from Contract c inner join fetch c.zsProject zsp ");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer(" zsp.id,c.groupCode,c.id ");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.andEq("zsp.id", zsProjectId);
        return this.pageHql(wrapper);
    }

    /**
     * 分页处理除了这一协议Id其他列表查询（面积调换使用）
     *
     * @return
     */
    public PageBean<Contract> contractPageBeanByProjectId(Integer contractId) {
        //查询语句
        StringBuffer query = new StringBuffer(" c from Contract c inner join fetch c.zsProject zsp ");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer(" zsp.id,c.groupCode,c.id ");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.getPageBean().setPageSize(5);
        wrapper.andEq("c.chooseHouseStatus", Status.NO.getIndex());
        wrapper.andNe("c.id", contractId);
        return this.pageHql(wrapper);
    }

    /**
     * 分页处理（查询已经选过房的）财务使用
     *
     * @return
     */
    public PageBean<Contract> getChoosedHousePageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.andEq("c.chooseHouseStatus", Status.YES.getIndex());
        wrapper.andNotNull("c.chooseHouseDate");   //选房时间不为空
        UserPermissionUtil.zsProjectUserLimit(wrapper); //用户只能看到已经分配给自己的项目下的协议信息
        return this.pageHql(wrapper);
    }


    /**
     * 分页处理（查询已经选过房的）
     *
     * @return
     */
    public PageBean<Contract> getChoosedHouseByAzProjectNamePageBean(String azProjectName, String startDate, String stopDate) {
        List<Integer> contractIdList = new ArrayList<>();
        contractIdList.add(0);//防止为空
        List<Integer> houseContractIdList = this.houseService.getContractIdListByAzProjectName(azProjectName, startDate, stopDate);
        List<Integer> carLotContractIdList = this.carLotService.getContractIdListByAzProjectName(azProjectName, startDate, stopDate);
        List<Integer> syorageRoomContractIdList = this.storageRoomService.getContractIdListByAzProjectName(azProjectName, startDate, stopDate);
        if (CollectionUtils.isNotEmpty(houseContractIdList)) {
            for (Integer i1 : houseContractIdList) {
                if (i1 != null)
                    contractIdList.add(i1);
            }
        }
        if (CollectionUtils.isNotEmpty(carLotContractIdList)) {
            for (Integer i2 : carLotContractIdList) {
                if (i2 != null)
                    contractIdList.add(i2);
            }
        }
        if (CollectionUtils.isNotEmpty(syorageRoomContractIdList)) {
            for (Integer i3 : syorageRoomContractIdList) {
                if (i3 != null)
                    contractIdList.add(i3);
            }
        }
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.andEq("c.chooseHouseStatus", Status.YES.getIndex());
        wrapper.andNotNull("c.chooseHouseDate");   //选房时间不为空
        wrapper.andIn("c.id", contractIdList);

        UserPermissionUtil.zsProjectUserLimit(wrapper); //用户只能看到已经分配给自己的项目下的协议信息
        return this.pageHql(wrapper);
    }

    /**
     * 查询已经选过房的  导出使用
     *
     * @return
     */
    public PageBean<Contract> getChoosedHouseExcelPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        PageBean pageBean = new PageBean();
        pageBean.setPageSize(Integer.MAX_VALUE);
        Wrapper wrapper = new Wrapper(pageBean, query, null, orderBy);
        wrapper.initSearchParams();
        wrapper.andEq("c.chooseHouseStatus", Status.YES.getIndex());
        wrapper.andNotNull("c.chooseHouseDate");   //选房时间不为空
        UserPermissionUtil.zsProjectUserLimit(wrapper); //用户只能看到已经分配给自己的项目下的协议信息
        return this.pageHql(wrapper);
    }

    /**
     * 分页处理（查询财务已经审核通过的）
     *
     * @return
     */
    public PageBean<Contract> getFinanceCheckedPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.andEq("c.financeCheckStatus", Status.YES.getIndex());   //财务审核通过
        UserPermissionUtil.zsProjectUserLimit(wrapper); //用户只能看到已经分配给自己的项目下的协议信息
        return this.pageHql(wrapper);
    }


    /**
     * 分页处理（查询已经签过安置协议，并且需要缴款的）
     *
     * @return
     */
    public PageBean<Contract> getAzSignAndFhPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.andEq("c.azSignStatus", Status.YES.getIndex());   //安置协议已签约
        wrapper.andEq("c.financeCheckStatus", Status.YES.getIndex());   //财务已复核
        UserPermissionUtil.zsProjectUserLimit(wrapper); //用户只能看到已经分配给自己的项目下的协议信息
        return this.pageHql(wrapper);
    }

    /**
     * 分页处理（契税审核列表）
     *
     * @return
     */
    public PageBean<Contract> getDeetListPageBean(String azProjectName) {
        List<Integer> contractIdList = new ArrayList<>();
        contractIdList.add(0);//防止为空
        List<Integer> houseContractIdList = this.houseService.getContractIdListByAzProjectName(azProjectName, null, null);
        List<Integer> carLotContractIdList = this.carLotService.getContractIdListByAzProjectName(azProjectName, null, null);
        List<Integer> syorageRoomContractIdList = this.storageRoomService.getContractIdListByAzProjectName(azProjectName, null, null);
        if (CollectionUtils.isNotEmpty(houseContractIdList)) {
            for (Integer i1 : houseContractIdList) {
                if (i1 != null)
                    contractIdList.add(i1);
            }
        }
        if (CollectionUtils.isNotEmpty(carLotContractIdList)) {
            for (Integer i2 : carLotContractIdList) {
                if (i2 != null)
                    contractIdList.add(i2);
            }
        }
        if (CollectionUtils.isNotEmpty(syorageRoomContractIdList)) {
            for (Integer i3 : syorageRoomContractIdList) {
                if (i3 != null)
                    contractIdList.add(i3);
            }
        }
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("c.chooseHouseNum,zsp.id,c.id");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.andIn("c.id", contractIdList);
        wrapper.andEq("c.chooseHouseStatus", Status.YES.getIndex());   //已签认
        UserPermissionUtil.zsProjectUserLimit(wrapper); //用户只能看到已经分配给自己的项目下的协议信息
        return this.pageHql(wrapper);
    }


    /**
     * 分页处理（查询已经财务结清的）
     *
     * @return
     */
    public PageBean<Contract> getCheckInPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.andEq("c.financeSettleStatus", Status.YES.getIndex());   //财务已结清
        UserPermissionUtil.zsProjectUserLimit(wrapper); //用户只能看到已经分配给自己的项目下的协议信息
        return this.pageHql(wrapper);
    }

    /**
     * 办证列表分页处理（查询已经发放档案的）
     *
     * @return
     */
    public PageBean<Contract> getBzListPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer("c from Contract c inner join fetch c.zsProject zsp");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("zsp.id,c.chooseHouseNum,c.id");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        wrapper.andEq("c.daffStatus", Status.YES.getIndex());   //档案已发放
        UserPermissionUtil.zsProjectUserLimit(wrapper); //用户只能看到已经分配给自己的项目下的协议信息
        return this.pageHql(wrapper);
    }

    /**
     * 查询某些征收项目下所分配的某些安置项目房源已经被选的家庭明细
     *
     * @return
     */
    public PageBean<Contract> getChoosedHouseContractPageBean(String zsProjectIdStr, String azProjectStr, Integer pageSize, Integer pageNo) {
        Date nowDate = new Date();
        StringBuffer hql = new StringBuffer("c from Contract c inner join fetch c.zsProject zp where c.chooseHouseStatus = 2 ");
        hql.append(" AND zp.id IN (" + zsProjectIdStr + ") ");
        hql.append(" AND DATE_FORMAT(c.chooseHouseDate,'%Y-%m-%d') = CURDATE()");
        /*if (DateUtils.stringToDateTimeCompare(nowDate).equals("上午")) {
            hql.append(" AND c.qrchooseHouseDate =1");
        } else if (DateUtils.stringToDateTimeCompare(nowDate).equals("下午")) {
            hql.append(" AND c.qrchooseHouseDate =2");
        }*/
        StringBuffer orderBy = new StringBuffer(" c.chooseHouseDate DESC ");
        PageBean pageBean = new PageBean();
        pageBean.setPageSize(pageSize);
        pageBean.setPageNum(pageNo);
        Wrapper wrapper = new Wrapper(pageBean, hql, null, orderBy);
        return this.pageHql(wrapper);
    }

    /**
     * 根据协议编号查询协议
     *
     * @return
     */
    public Contract getContractByContractCode(String contractCode) {
        List<Contract> list = this.findEqualField("contractCode", contractCode);
        if (list.size() > 0 && list != null) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 查询所有的协议编号
     *
     * @return
     */
    public List<String> getContractCodeList(Integer zsProjectId) {
        StringBuffer sql = new StringBuffer("select c.contract_code from contract c  where c.zs_project_id = :zsProjectId order by c.contract_code desc");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("zsProjectId", zsProjectId);
        List list = this.findSqlObject(sql.toString(), map);
        return list;
    }


    /**
     * 查询某征收项目下的基础信息
     *
     * @param zsProjectId
     * @return
     */
    public List<Contract> getContractListByZsProjectId(Integer zsProjectId) {
        StringBuffer hql = new StringBuffer(" from Contract c where c.zsProject.id = :zsProjectId order by c.chooseHouseNum ");
        Map<String, Object> map = new HashMap<>();
        map.put("zsProjectId", zsProjectId);
        return this.findHql(hql.toString(), map);
    }

    public List<Contract> getContractListChooseHouse(Integer chooseHouseStatus) {
        StringBuffer hql = new StringBuffer(" from Contract c where c.chooseHouseStatus = :chooseHouseStatus order by c.chooseHouseNum ");
        Map<String, Object> map = new HashMap<>();
        map.put("chooseHouseStatus", chooseHouseStatus);
        return this.findHql(hql.toString(), map);
    }

    /**
     * 查询某征收项目下的安排选房时间
     *
     * @param zsProjectId
     * @return 去重的安排选房时间list
     */
    public List getPreChooseDateByZsProjectId(Integer zsProjectId) {
        StringBuffer sql = new StringBuffer("select pre_choose_date,count(id) as cnt from contract c where c.zs_project_id = :zsProjectId and c.pre_choose_date is not null group by c.pre_choose_date order by c.pre_choose_date,contract_code desc");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("zsProjectId", zsProjectId);

        return this.findSqlObject(sql.toString(), map);
    }

    /**
     * 查询某征收项目下的最大选房顺序号
     *
     * @param zsProjectId
     * @return
     */
    public int getChooseNumByZsProjectId(Integer zsProjectId) {
        StringBuffer sql = new StringBuffer("select IFNULL(MAX(c.choose_house_num),0) from contract c where c.zs_project_id = :zsProjectId ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("zsProjectId", zsProjectId);
        return Integer.valueOf(String.valueOf(this.findSqlObject(sql.toString(), map).get(0)));
    }

    /**
     * 查询某征收项目下的基础信息（安排选房时间不为空）
     *
     * @param zsProjectId
     * @return
     */
    public List<Contract> getContractListByZsProjectIdAndPreChooseDateIsNotNull(Integer zsProjectId) {
        StringBuffer hql = new StringBuffer(" from Contract c where c.zsProject.id = :zsProjectId and c.preChooseDate is not null order by c.chooseHouseNum ");
        Map<String, Object> map = new HashMap<>();
        map.put("zsProjectId", zsProjectId);
        return this.findHql(hql.toString(), map);
    }

    /**
     * 查询某征收项目下的基础信息（安排选房时间不为空）的数量
     *
     * @param zsProjectId
     * @return
     */
    public Long countContractListPreChooseDateIsNotNull(Integer zsProjectId) {
        StringBuffer sql = new StringBuffer(" select count(c.id) as cnt from Contract c where c.zs_Project_id = :zsProjectId and c.pre_Choose_Date is not null order by c.choose_House_Num ");
        Map<String, Object> map = new HashMap<>();
        map.put("zsProjectId", zsProjectId);
        return this.countSql(sql.toString(), map);
    }

    /**
     * 查询某征收项目下的没有选过房的基础信息（选房时间安排专用）
     *
     * @param zsProjectId
     * @return
     */
    public List<Contract> getContractListByZsProjectIdChooseHouseDateIsNull(Integer zsProjectId) {
        StringBuffer hql = new StringBuffer(" from Contract c where c.zsProject.id = :zsProjectId and (c.chooseHouseDate is null or c.chooseHouseDate = '') order by c.chooseHouseNum ");
        Map<String, Object> map = new HashMap<>();
        map.put("zsProjectId", zsProjectId);
        return this.findHql(hql.toString(), map);
    }

    /**
     * 根据选房安排时间查询某征收项目下的基础信息
     *
     * @param zsProjectId
     * @param preChooseDate
     * @return
     */
    public List<Contract> getContractListByZsProjectIdAndPreChooseDate(Integer zsProjectId, String preChooseDate) {
        if (zsProjectId == null || StringUtils.isEmpty(preChooseDate)) {
            return null;
        }
        StringBuffer hql = new StringBuffer(" from Contract c where c.zsProject.id = " + zsProjectId + " ");
        hql.append(" and convert(c.preChooseDate,char(10)) in (" + preChooseDate + ") and c.preChooseDate is not null order by c.chooseHouseNum ");
        return this.findHql(hql.toString(), null);
    }

    /**
     * 根据拼接的选房顺序号范围查询某征收项目下的基础信息
     *
     * @param zsProjectId
     * @param chooseHouseNum
     * @return
     */
    public List<Contract> getContractListByZsProjectIdAndChooseHouseNum(Integer zsProjectId, String chooseHouseNum) {
        if (zsProjectId == null || StringUtils.isEmpty(chooseHouseNum)) {
            return null;
        }

        String[] chooseNumArry = chooseHouseNum.split(",");//前台传的选房顺序号范围的数组

        String[] numArray;//复选框选的值的数组
        String begin = null, end = null;
        StringBuffer hql = new StringBuffer(" from Contract c where c.zsProject.id = " + zsProjectId + " and (");
        for (String chooseNum : chooseNumArry) {
            numArray = chooseNum.split("-");
            begin = numArray[0];
            end = numArray[1];
            hql.append("(chooseHouseNum >= " + begin + " and chooseHouseNum <= " + end + ") or");
        }
        if (hql.length() > 0) {
            hql = new StringBuffer(hql.substring(0, hql.length() - 3));
            hql.append(")");
        }

        return this.findHql(hql.toString(), null);
    }

//    /**
//     * 批量设置选房安排时间
//     *
//     * @param zsProject
//     */
//    @Transactional
//    public Response batchSetChooseDate(ZsProject zsProject) {
//        //征收项目时间判断
//        Date startDate = zsProject.getStartYear();
//        String morningTime = zsProject.getMorningTime(), afternoonTime = zsProject.getAfternoonTime();
//        Precondition.checkAjaxArguement(startDate != null, "0022", "选房开始日期为空，请先填写！");
//        Precondition.checkAjaxArguement(morningTime != null, "0022", "上午开始时间为空，请先填写！");
//        Precondition.checkAjaxArguement(IntegerUtils.getNotNull(zsProject.getMorningCount()) != 0, "0022", "上午选房人数为空，请先填写！");
//        Precondition.checkAjaxArguement(IntegerUtils.getNotNull(zsProject.getAfternoonCount()) != 0, "0022", "下午选房人数为空，请先填写！");
//        int morningCnt = zsProject.getMorningCount(), afternoonCnt = zsProject.getAfternoonCount(), zsProjectId = zsProject.getId(), cnt = morningCnt + afternoonCnt;
//
//        //已经设置过选房安排时间内的基础信息的数量
//        Long setContractSize = this.countContractListPreChooseDateIsNotNull(zsProjectId);
//        //如果该项目下有一条信息已经设置过选房安排时间，则不允许进行批量设置
//        Precondition.checkAjaxArguement(setContractSize == 0, "0022", "该项目已经设置过选房安排时间！");
//
//        Calendar c = Calendar.getInstance();
//        c.setTime(startDate);
//
//        List<Contract> contractSetList = new ArrayList<>();//待设置的基础信息列表
//
//        int index = 0;
//        //查询该项目下的基础信息
//        List<Contract> contractList = getContractListByZsProjectId(zsProjectId);
//        int size = contractList.size();
//        Precondition.checkAjaxArguement(contractList != null && size > 0, "0022", "该项目下还未录入基础信息！");
//
//        //循环次数
//        int time = size / cnt;
//        //如果有余数
//        if (size % cnt > 0) {
//            time++;
//        }
//
//        int i = 1, times = 1, numLeft = i * morningCnt + (i - 1) * cnt, numRight = i * cnt;
//
//        for (Contract contract : contractList) {
//            if (index > times * cnt) {
//                i++;
//                times++;
//
//                numLeft = 1 * morningCnt + (i - 1) * cnt;
//                numRight = i * cnt;
//            }
//
//            if (index <= numLeft) { //设置上午安排选房时间段
//                contract.setBetweenChooseDate(morningTime);
//            } else if (index > numLeft && index <= numRight) {//设置下午安排选房时间段
//                contract.setBetweenChooseDate(afternoonTime);
//            }
//
//            if (index <= numRight) {//设置安排选房时间
//                contract.setPreChooseDate(DateUtils.stringToDateDefault(DateUtils.dateToStringFormat(c.getTime(), "yyyy-MM-dd")));
//            }
//
//            if (index == numRight - 1) {
//                c.add(Calendar.DAY_OF_MONTH, 1);// 日期+1天
//            }
//
//            contractSetList.add(contract);
//            index++;
//        }
//        batchSave(contractSetList);
//        return new Response("0001", "选房时间安排设置成功！");
//    }

    /**
     * 统计打印数量
     *
     * @param request
     * @return
     */
    public Integer countContractSize(HttpServletRequest request) {
        int zsProjectId = ParamUtils.getInt(request, "zsProjectId", 0);
        String preChooseDate = ParamUtils.getString(request, "preChooseDate", "");
        String chooseHouseNum = ParamUtils.getString(request, "chooseHouseNum", "");
        Precondition.checkAjaxArguement(zsProjectId != 0, "1111", "数据错误！");

        List<Contract> contractList = new ArrayList<>();

        if (StringUtils.isNotEmpty(preChooseDate)) {//
            contractList = this.getContractListByZsProjectIdAndPreChooseDate(zsProjectId, preChooseDate);
        } else {
            contractList = this.getContractListByZsProjectIdAndPreChooseDateIsNotNull(zsProjectId);
        }
        if (CollectionUtils.isNotEmpty(contractList)) {
            return contractList.size();
        }
        return 0;
    }


    /**
     * 剩余面积是否结算并进行计算
     *
     * @param request
     * @return
     */
    @Transactional
    public synchronized Response setIsJiSuanStatus(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Integer contractId = ParamUtils.getInt(request, "contractId", 0);
        Integer isJiSuan = ParamUtils.getInt(request, "isJiSuan", 0);
        Contract contract = this.findOne(contractId);
        Precondition.checkAjaxArguement(contract != null, "0012", "找不到该户信息！");
        UserInfo userInfo = WebUtils.getLoginUserInfo();
        Precondition.checkSqdsArguement(contract.getChooseHouseStatus() != Status.YES.getIndex(), "该户已签认，无法修改");

        WebUtils.bind(request, contract);
        this.save(contract);
        CalculateUtils.main(contract.getId());
        this.actionHistoryService.saveActionHistoryByContractId(contract.getId(), "结算状态：改为：" + isJiSuan, "结算状态");

        Response response = new Response();
        response.setCode("0001");
        return response;
    }


//    /**
//     * 批量执行某项目计算方法《未用》
//     *
//     * @param zsProject
//     * @return
//     */
//    @Transactional
//    public Response batchSetCalculate(ZsProject zsProject) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//        List<Contract> contractList = new ArrayList<>();
//        contractList = this.getContractListByMemo();
//        if (CollectionUtils.isNotEmpty(contractList)) {
//            for (Contract contract : contractList) {
//                CalculateUtils.main(contract.getId());
//
//            }
//        }
//        return new Response("0001", "计算方法批量设置成功！");
//    }
//

    /**
     * 设置协议下所有房源、车位的结清\未结清状态
     *
     * @param contract
     * @return
     */
    @Transactional
    public void setHouseFinanceSettleStatus(Contract contract) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        List<House> houseList = this.houseService.getHouseListByContractId(contract.getId());
        List<CarLot> carLotList = this.carLotService.getCarLotListByContractId(contract.getId());
        List<ShopHouse> shopHouseList = this.shopHouseService.getShopHouseListByContractId(contract.getId());
        if (CollectionUtils.isNotEmpty(houseList)) {
            for (House house : houseList) {
                if (contract.getFinanceSettleStatus().equals(Status.YES.getIndex())) {
                    house.setFinanceSettleStatus(Status.YES.getIndex());
                    house.setFinanceSettleDate(new Date());
                } else if (contract.getFinanceSettleStatus().equals(Status.NO.getIndex())) {
                    house.setFinanceSettleStatus(Status.NO.getIndex());
                    house.setFinanceSettleDate(new Date());
                }
                this.houseService.save(house);
            }
        }
        if (CollectionUtils.isNotEmpty(carLotList)) {
            for (CarLot carLot : carLotList) {
                if (contract.getFinanceSettleStatus().equals(Status.YES.getIndex())) {
                    carLot.setFinanceSettleStatus(Status.YES.getIndex());
                    carLot.setFinanceSettleDate(new Date());
                } else if (contract.getFinanceSettleStatus().equals(Status.NO.getIndex())) {
                    carLot.setFinanceSettleStatus(Status.NO.getIndex());
                    carLot.setFinanceSettleDate(new Date());
                }
                this.carLotService.save(carLot);
            }
        }

        if (CollectionUtils.isNotEmpty(shopHouseList)) {
            for (ShopHouse shopHouse : shopHouseList) {
                if (contract.getFinanceSettleStatus().equals(Status.YES.getIndex())) {
                    shopHouse.setFinanceSettleStatus(Status.YES.getIndex());
                    shopHouse.setFinanceSettleDate(new Date());
                } else if (contract.getFinanceSettleStatus().equals(Status.NO.getIndex())) {
                    shopHouse.setFinanceSettleStatus(Status.NO.getIndex());
                    shopHouse.setFinanceSettleDate(new Date());
                }
                this.shopHouseService.save(shopHouse);
            }
        }
    }


    /**
     * 根据房源、车位状态设置该户是否是未结清状态
     *
     * @param contract
     * @return
     */
    @Transactional
    public void setFinanceSettleStatus(Contract contract) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        Precondition.checkAjaxArguement(contract.getLimitStatus() != 3, "1111", "该户不可结算交房，请确认无误后联系技术支持修改！");
        List<House> houseList = this.houseService.getHouseListByContractId(contract.getId());
        List<CarLot> carLotList = this.carLotService.getCarLotListByContractId(contract.getId());
        if (CollectionUtils.isNotEmpty(houseList)) {
            for (House house : houseList) {
                if (house.getFinanceSettleStatus().equals(Status.YES.getIndex())) {
                    contract.setFinanceSettleStatus(Status.YES.getIndex());
                    contract.setFinanceSettleDate(new Date());
                } else if (house.getFinanceSettleStatus().equals(Status.NO.getIndex())) {
                    contract.setFinanceSettleStatus(Status.TUI.getIndex());
                    contract.setFinanceSettleDate(new Date());
                    return;
                }
                this.save(contract);
            }
        }
        if (CollectionUtils.isNotEmpty(carLotList)) {
            for (CarLot carLot : carLotList) {
                if (carLot.getFinanceSettleStatus().equals(Status.YES.getIndex())) {
                    contract.setFinanceSettleStatus(Status.YES.getIndex());
                    contract.setFinanceSettleDate(new Date());
                } else if (carLot.getFinanceSettleStatus().equals(Status.NO.getIndex())) {
                    contract.setFinanceSettleStatus(Status.TUI.getIndex());
                    contract.setFinanceSettleDate(new Date());
                    return;
                }
                this.save(contract);
            }
        }
    }


    /**
     * 根据房源交房状态设置该户交房状态
     *
     * @param contract
     * @return
     */
    @Transactional
    public void setContractTakeHouseStatus(Contract contract) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        List<Integer> statusList = this.getStatusByContractIdAndStatus(contract.getId(), "take_house_status");
        List<Date> dateList = this.getDateByContractIdAndStatus(contract.getId(), "take_house_date");
        Date maxDate = null;
        if (CollectionUtils.isNotEmpty(dateList)) {
            maxDate = dateList.get(0);
        }
        if (CollectionUtils.isNotEmpty(statusList)) {
            if (statusList.contains(1) && !statusList.contains(2)) {
                contract.setTakeHouseStatus(Status.NO.getIndex());
                contract.setTakeHouseDate(null);
            } else if (!statusList.contains(1) && statusList.contains(2)) {
                contract.setTakeHouseStatus(Status.YES.getIndex());
                contract.setTakeHouseDate(maxDate);
            } else if (statusList.contains(1) && statusList.contains(2)) {
                contract.setTakeHouseStatus(Status.TUI.getIndex());
                contract.setTakeHouseDate(maxDate);
            }
        }
    }


    /**
     * 根据房源装修状态设置该户装修状态
     *
     * @param contract
     * @return
     */
    @Transactional
    public void setContractZxStatus(Contract contract) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        List<Integer> statusList = this.getStatusByContractIdAndStatus(contract.getId(), "zx_status");
        List<Date> dateList = this.getDateByContractIdAndStatus(contract.getId(), "zx_date");
        Date maxDate = null;
        if (CollectionUtils.isNotEmpty(dateList)) {
            maxDate = dateList.get(0);
        }
        if (CollectionUtils.isNotEmpty(statusList)) {
            if (statusList.contains(1) && !statusList.contains(2)) {
                contract.setZxStatus(Status.NO.getIndex());
                contract.setZxDate(null);
            } else if (!statusList.contains(1) && statusList.contains(2)) {
                contract.setZxStatus(Status.YES.getIndex());
                contract.setZxDate(maxDate);
            } else if (statusList.contains(1) && statusList.contains(2)) {
                contract.setZxStatus(Status.TUI.getIndex());
                contract.setZxDate(maxDate);
            }
        }
    }


    /**
     * 根据房源入住状态设置该户入住状态
     *
     * @param contract
     * @return
     */
    @Transactional
    public void setContractRzStatus(Contract contract) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        List<Integer> statusList = this.getStatusByContractIdAndStatus(contract.getId(), "rz_status");
        List<Date> dateList = this.getDateByContractIdAndStatus(contract.getId(), "rz_date");
        Date maxDate = null;
        if (CollectionUtils.isNotEmpty(dateList)) {
            maxDate = dateList.get(0);
        }
        if (CollectionUtils.isNotEmpty(statusList)) {
            if (statusList.contains(1) && !statusList.contains(2)) {
                contract.setRzStatus(Status.NO.getIndex());
                contract.setRzDate(null);
            } else if (!statusList.contains(1) && statusList.contains(2)) {
                contract.setRzStatus(Status.YES.getIndex());
                contract.setRzDate(maxDate);
            } else if (statusList.contains(1) && statusList.contains(2)) {
                contract.setRzStatus(Status.TUI.getIndex());
                contract.setRzDate(maxDate);
            }
        }
    }


    /**
     * 根据房源办证状态设置该户办证状态
     *
     * @param contract
     * @return
     */
    @Transactional
    public void setContractBzStatus(Contract contract) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        List<Integer> statusList = this.getStatusByContractIdAndStatus(contract.getId(), "bz_status");
        List<Date> dateList = this.getDateByContractIdAndStatus(contract.getId(), "bz_date");
        Date maxDate = null;
        if (CollectionUtils.isNotEmpty(dateList)) {
            maxDate = dateList.get(0);
        }
        if (CollectionUtils.isNotEmpty(statusList)) {
            if (statusList.contains(1) && !statusList.contains(2)) {
                contract.setBzStatus(Status.NO.getIndex());
                contract.setBzDate(null);
            } else if (!statusList.contains(1) && statusList.contains(2)) {
                contract.setBzStatus(Status.YES.getIndex());
                contract.setBzDate(maxDate);
            } else if (statusList.contains(1) && statusList.contains(2)) {
                contract.setBzStatus(Status.TUI.getIndex());
                contract.setBzDate(maxDate);
            }
        }
    }


    /**
     * 根据协议id和状态获取状态类别
     *
     * @param contractId
     * @param status
     * @return
     */
    public List<Integer> getStatusByContractIdAndStatus(Integer contractId, String status) {

        Map<String, Object> map = Maps.newLinkedHashMap();
        StringBuffer sql = new StringBuffer("(select h.");
        sql.append(status);
        sql.append(" from house h  where h.contract_id = :contractId)  ");
        if (!status.equals("zx_status")) {
            sql.append(" union ");
            sql.append(" (select cl.");
            sql.append(status);
            sql.append(" from car_Lot cl  where cl.contract_id = :contractId)  ");
        }
        map.put("contractId", contractId);
        return this.findSqlObject(sql.toString(), map);
    }

    /**
     * 根据协议id和状态获取该状态最大时间
     *
     * @param contractId
     * @param status
     * @return
     */
    public List<Date> getDateByContractIdAndStatus(Integer contractId, String statusDateStr) {

        Map<String, Object> map = Maps.newLinkedHashMap();
        StringBuffer sql = new StringBuffer(" select max(r.maxDate) from ((select h.");
        sql.append(statusDateStr);
        sql.append(" as maxDate from house h  where h.contract_id = :contractId)  ");
        if (!statusDateStr.equals("zx_date")) {
            sql.append(" union ");
            sql.append(" (select c.");
            sql.append(statusDateStr);
            sql.append(" as maxDate from car_Lot c  where c.contract_id = :contractId)  ");
        }
        sql.append(" ) r");
        map.put("contractId", contractId);
        return this.findSqlObject(sql.toString(), map);
    }

    /**
     * 得到某一户剩余期房面积
     * 未结算剩余面积
     *
     * @return
     */
    public BigDecimal getSyAreaByAzContractId(Integer contractId) {
        StringBuffer sql = new StringBuffer(" SELECT IFNULL(c.sycqdh_Area+c.syzggm_Area,0)  AS syArea ");
        sql.append(" FROM contract c  ");
        sql.append(" WHERE c.is_Ji_Suan =2 and c.id = :contractId ");
        Map<String, Object> map = new HashMap<>();
        map.put("contractId", contractId);
        return BigDecimalUtils.stringToBigDecimal(String.valueOf(this.findSqlObject(sql.toString(), map).get(0)));
    }


    /**
     * 根据协议ID得到各照顾购买面积及单价
     *
     * @return
     */
    public Map<String, String> getAreaAndPriceMap(Integer contractId) {

        StringBuffer sql = new StringBuffer(" SELECT sum(cba.careBuyArea) as careBuyArea,cba.careBuyAreaPrice as careBuyAreaPrice FROM (  ");
        sql.append(" SELECT IFNULL(c.care_buy_area1,0) - IFNULL(c.ck_care_buy_area1,0) AS careBuyArea,c.`care_buy_area1price` AS careBuyAreaPrice FROM contract  c WHERE c.id= " + contractId);
        sql.append(" UNION ALL");
        sql.append(" SELECT IFNULL(c.care_buy_area2,0) - IFNULL(c.ck_care_buy_area2,0) AS careBuyArea,c.`care_buy_area2price` AS careBuyAreaPrice FROM contract  c WHERE c.id= " + contractId);
        sql.append(" UNION ALL");
        sql.append(" SELECT IFNULL(c.care_buy_area3,0) - IFNULL(c.ck_care_buy_area3,0) AS careBuyArea,c.`care_buy_area3price` AS careBuyAreaPrice FROM contract  c WHERE c.id= " + contractId);
        sql.append(" UNION ALL");
        sql.append(" SELECT IFNULL(c.care_buy_area4,0) - IFNULL(c.ck_care_buy_area4,0) AS careBuyArea,c.`care_buy_area4price` AS careBuyAreaPrice FROM contract  c WHERE c.id= " + contractId);
        sql.append(" UNION ALL");
        sql.append(" SELECT IFNULL(c.care_buy_area5,0) - IFNULL(c.ck_care_buy_area5,0) AS careBuyArea,c.`care_buy_area5price` AS careBuyAreaPrice FROM contract  c WHERE c.id= " + contractId);
        sql.append(" UNION ALL");
        sql.append(" SELECT IFNULL(c.care_buy_area6,0) - IFNULL(c.ck_care_buy_area6,0) AS careBuyArea,c.`care_buy_area6price` AS careBuyAreaPrice FROM contract  c WHERE c.id= " + contractId);
        sql.append(" UNION ALL");
        sql.append(" SELECT IFNULL(c.care_buy_area7,0) - IFNULL(c.ck_care_buy_area7,0) AS careBuyArea,c.`care_buy_area7price` AS careBuyAreaPrice FROM contract  c WHERE c.id= " + contractId);
        sql.append(" UNION ALL");
        sql.append(" SELECT IFNULL(c.care_buy_area8,0) - IFNULL(c.ck_care_buy_area8,0) AS careBuyArea,c.`care_buy_area8price` AS careBuyAreaPrice FROM contract  c WHERE c.id= " + contractId);
        sql.append(" ) cba");
        sql.append(" WHERE cba.careBuyArea IS NOT NULL AND cba.careBuyArea > 0 ");
        sql.append(" GROUP BY cba.careBuyAreaPrice ORDER BY cba.careBuyAreaPrice");

        Query query = this.entityManager.createNativeQuery(sql.toString());
        List<Map> mapList = query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        Map<String, String> areaAndPriceMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(mapList)) {
            for (Map map : mapList) {
                String careBuyAreaPrice = map.get("careBuyAreaPrice") == null ? "0" : map.get("careBuyAreaPrice").toString();
                String careBuyArea = map.get("careBuyArea") == null ? "0" : map.get("careBuyArea").toString();
                areaAndPriceMap.put(careBuyAreaPrice, careBuyArea);
            }
        }
        return areaAndPriceMap;
    }

    /**
     * 设置协议下所有房源、车位的结清\未结清状态
     *
     * @param contract
     * @return
     */
    @Transactional
    public void setDeedStatusSh(Contract contract) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        List<House> houseList = this.houseService.getHouseListByContractId(contract.getId());
        List<CarLot> carLotList = this.carLotService.getCarLotListByContractId(contract.getId());
        List<StorageRoom> storageRoomList = this.storageRoomService.getStorageRoomListByContractId(contract.getId());
        if (CollectionUtils.isNotEmpty(houseList)) {
            for (House house : houseList) {
                if (contract.getDeedShStatus().equals(Status.YES.getIndex())) {
                    house.setDeedShStatus(Status.YES.getIndex());
                    house.setDeedShDate(new Date());
                } else if (contract.getDeedShStatus().equals(Status.NO.getIndex())) {
                    house.setDeedShStatus(Status.NO.getIndex());
                    house.setDeedShDate(new Date());
                }
                this.houseService.save(house);
            }
        }
        if (CollectionUtils.isNotEmpty(carLotList)) {
            for (CarLot carLot : carLotList) {
                if (contract.getDeedShStatus().equals(Status.YES.getIndex())) {
                    carLot.setDeedShStatus(Status.YES.getIndex());
                    carLot.setDeedShDate(new Date());
                } else if (contract.getDeedShStatus().equals(Status.NO.getIndex())) {
                    carLot.setDeedShStatus(Status.NO.getIndex());
                    carLot.setDeedShDate(new Date());
                }
                this.carLotService.save(carLot);
            }
        }
        if (CollectionUtils.isNotEmpty(storageRoomList)) {
            for (StorageRoom storageRoom : storageRoomList) {
                if (contract.getDeedShStatus().equals(Status.YES.getIndex())) {
                    storageRoom.setDeedShStatus(Status.YES.getIndex());
                    storageRoom.setDeedShDate(new Date());
                } else if (contract.getDeedShStatus().equals(Status.NO.getIndex())) {
                    storageRoom.setDeedShStatus(Status.NO.getIndex());
                    storageRoom.setDeedShDate(new Date());
                }
                this.storageRoomService.save(storageRoom);
            }
        }
    }

    /**
     * 通过车位、房屋、储藏间状态设置审核时间
     * @param contract
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    @Transactional
    public void setDeedShStatusByItem(Contract contract) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        List<String> houseList = this.houseService.getHouseDeedShStatusList(contract.getId());
        List<String> carLotList = this.carLotService.getCarLotDeedShStatusList(contract.getId());
        List<String> storageRoomList = this.storageRoomService.getStorageRoomDeedShStatusList(contract.getId());
        List<String> list = mergeList(houseList,carLotList,storageRoomList);
        if (list.contains(1) && list.contains(2)) {
            contract.setDeedShStatus(Status.TUI.getIndex());//部分审核
            contract.setDeedShDate(new Date());
        } else if (list.contains(1) && !list.contains(2)) {
            contract.setDeedShStatus(Status.NO.getIndex());//未审核
            contract.setDeedShDate(new Date());
        } else {
            contract.setDeedShStatus(Status.YES.getIndex());//审核
            contract.setDeedShDate(new Date());
        }
        this.save(contract);
    }

    public static <T> List<T> mergeList(List<T>... list){
        List<T> res = new ArrayList<>();
        if (Objects.nonNull(list)) {
            for (List<T> l : list) {
                res.addAll(l);
            }
        }
        return res;
    }


    /**
     * 预选前期 身份证号后四位及选房号存在验证
     * @param chooseHouseNum
     * @param idCardFour
     * @return
     */
    public String validateForYx(String chooseHouseNum, String idCardFour) {
        StringBuffer hql = new StringBuffer(" select id from contract where choose_house_num =:chooseHouseNum and RIGHT(id_card, 4) =:idCardFour ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("chooseHouseNum", chooseHouseNum);
        map.put("idCardFour", idCardFour);
        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            Contract contract = findOne(Integer.valueOf(list.get(0).toString()));
            if (contract.getZsProject().getId() == 5 || contract.getZsProject().getId() == 6 || contract.getZsProject().getId() == 7){//2024年12月禁止登录
                return "0000";//数据不存在
            } else {
                return list.get(0).toString();//返回查到的协议Id
            }
        } else {
            return "0000";//数据不存在
        }
    }

    /**
     * 预约办证 身份证号后四位及选房号存在验证
     * @param chooseHouseNum
     * @param idCardFour
     * @return
     */
    public String validateForYyBz(String chooseHouseNum, String idCardFour) {
        StringBuffer hql = new StringBuffer(" select id from contract where choose_house_num =:chooseHouseNum and RIGHT(id_card, 4) =:idCardFour and zs_project_id in (5,6,7,2,8) ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("chooseHouseNum", chooseHouseNum);
        map.put("idCardFour", idCardFour);
        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            Contract contract = findOne(Integer.valueOf(list.get(0).toString()));
            if (contract.getSfStatus() == 2) {
                return "8888";//目前走司法状态 不可预约
            } else {
                return list.get(0).toString();//返回查到的协议Id
            }
        } else {
            return "0000";//数据不存在
        }
    }

    /**
     * 得到第一条预选信息的状态
     * @param chooseHouseNum
     * @param idCardFour
     * @return
     */
    public String getChooseHouseStatus(String chooseHouseNum, String idCardFour) {
        StringBuffer hql = new StringBuffer(" select choose_house_status from contract where choose_house_num =:chooseHouseNum and RIGHT(id_card, 4) =:idCardFour ");
        hql.append("and zs_project_id in (5) ");//目前只开放南区第一批次
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("chooseHouseNum", chooseHouseNum);
        map.put("idCardFour", idCardFour);
        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0).toString();//返回查到的协议选房状态
        } else {
            return "0000";//数据不存在
        }
    }

    /**
     * 得到结清状态
     * @param chooseHouseNum
     * @param idCardFour
     * @return
     */
    public String getJqStatus(String chooseHouseNum, String idCardFour) {
        StringBuffer hql = new StringBuffer(" select finance_settle_status from contract where choose_house_num =:chooseHouseNum and RIGHT(id_card, 4) =:idCardFour ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("chooseHouseNum", chooseHouseNum);
        map.put("idCardFour", idCardFour);
        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0).toString();//返回查到的协议选房状态
        } else {
            return "0000";//数据不存在
        }
    }

    /**
     * 得到第一条预选信息办证的状态
     * @param chooseHouseNum
     * @param idCardFour
     * @return
     */
    public String getBzStatus(String chooseHouseNum, String idCardFour) {
        StringBuffer hql = new StringBuffer(" select choose_house_status from contract where choose_house_num =:chooseHouseNum and RIGHT(id_card, 4) =:idCardFour ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("chooseHouseNum", chooseHouseNum);
        map.put("idCardFour", idCardFour);
        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0).toString();//返回查到的协议选房状态
        } else {
            return "0000";//数据不存在
        }
    }

    /**
     * 通过办证时间预约办证户数
     * @param bzYyDate
     * @return
     */
    public synchronized Integer getContractListByBzYyDateNum(String bzYyDate,String time) {
        StringBuffer hql = new StringBuffer(" from Contract c where DATE_FORMAT(c.bzYyDate, '%Y-%m-%d') = :bzYyDate AND c.time = :time  ");
        Map<String, Object> map = new HashMap<>();
        map.put("bzYyDate", bzYyDate);
        map.put("time", time);
        List<Contract> contractList = this.findHql(hql.toString(), map);
        int bzYyNum = 0;
        if (CollectionUtils.isNotEmpty(contractList)){
            return contractList.size();
        } else {
            return bzYyNum;
        }
    }

    /**
     * 得到已过去的已预约未办证的状态
     * @return
     */
    public List<Contract> getNoBzContractList() {
        StringBuffer hql = new StringBuffer(" from Contract c where DATE_FORMAT(c.bzYyDate, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d')  ");
        hql.append("and c.bzStatus = 1 and c.bzYyStatus =:bzYyStatus ");
        Map<String, Object> map = new HashMap<>();
        map.put("bzYyStatus",2);
        List<Contract> contractList = this.findHql(hql.toString(), map);
        return contractList;
    }


    /**
     * 预约办证时间对应数量
     * @return
     */
    public Map<String, String> getBzYyNumMap() {
        StringBuffer sql = new StringBuffer("SELECT DATE_FORMAT(c.bz_yy_date, '%Y-%m-%d') AS 'bzYxDate',c.time,COUNT(c.id) AS 'bzYyNum' FROM Contract c GROUP BY DATE_FORMAT(c.bz_yy_date, '%Y-%m-%d'),c.time ");
        Query query = this.entityManager.createNativeQuery(sql.toString());
        List<Map> mapList = query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        Map<String, String> getBzYyNumMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(mapList)) {
            for (Map map : mapList) {
                String bzYxDate = map != null && map.get("bzYxDate") != null ? map.get("bzYxDate").toString() : "11";
                String time = map != null && map.get("time") != null ? map.get("time").toString() : "";
                String bzYyNum = map != null && map.get("bzYyNum") != null ? map.get("bzYyNum").toString() : "0";
                String key = bzYxDate + "_" + time;
                getBzYyNumMap.put(key,bzYyNum);
            }
        }
        return getBzYyNumMap;
    }
}
